-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New ABI encoder #2704
New ABI encoder #2704
Conversation
What experimental pragma to use?
|
libsolidity/codegen/CompilerUtils.h
Outdated
@@ -103,6 +103,12 @@ class CompilerUtils | |||
bool _encodeAsLibraryTypes = false | |||
); | |||
|
|||
void abiEncode( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should have some documentation above.
libsolidity/codegen/ABIFunctions.cpp
Outdated
{ | ||
// This throws an exception and thus might cause immediate termination, but hey, | ||
// it's a failed assertion anyway :-) | ||
//TODO solAssert(m_requestedFunctions.empty(), "Forgot to call ``requestedFunctions()``."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about this here?
Can you please rebase? |
This allows multi-dimensional arrays in interfaces unconditionally, i.e. now only if the experimental mode is turned on. This is more or less required because it is a type feature. I don't think this is harmful, because it will only cause an "unimplemented feature" exception in the code generator. I don't think it changes any interfaces, but I'm not 100% positive on that. |
@@ -1528,8 +1528,6 @@ TypePointer ArrayType::interfaceType(bool _inLibrary) const | |||
TypePointer baseExt = m_baseType->interfaceType(_inLibrary); | |||
if (!baseExt) | |||
return TypePointer(); | |||
if (m_baseType->category() == Category::Array && m_baseType->isDynamicallySized()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you fold this change into another commit or rename the commit message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
libsolidity/codegen/ABIFunctions.cpp
Outdated
"_to_" + | ||
_to.identifier() + | ||
(_encodeAsLibraryTypes ? "_lib" : "") + | ||
(_compacted ? "_comp" : ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_compact
?
Ok, hopefully no failures anymore now. |
Fails on:
|
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); | ||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)"))); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(event_really_lots_of_data_from_storage) | ||
{ | ||
char const* sourceCode = R"( | ||
pragma experimental ABIEncoderV2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chriseth I think this is still added to the wrong test here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay reordered this in the commits as it was confusing.
I haven't reviewed the actual encoder yet, but the rest (bar the above) seems ok. |
libsolidity/codegen/ABIFunctions.cpp
Outdated
break; | ||
} | ||
case Type::Category::Contract: | ||
templ("body", "cleaned := " + cleanupFunction(IntegerType(120, IntegerType::Modifier::Address)) + "(value)"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be 160, Address
, though I guess the bits is ignored if it is an address. It would make sense adding another constructor in that case.
toCategory == Type::Category::Integer || | ||
toCategory == Type::Category::Contract, | ||
""); | ||
IntegerType const addressType(0, IntegerType::Modifier::Address); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, 160, Address
I guess.
libsolidity/codegen/ABIFunctions.cpp
Outdated
Whiskers("converted := <shiftLeft>(<clean>(value))") | ||
("shiftLeft", shiftLeftFunction(256 - toBytesType.numBytes() * 8)) | ||
("clean", cleanupFunction(_from)) | ||
.render(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The formatting on these is a bit misleading, probably this is more readable:
Whiskers(...)
("shiftLeft",...)
...
.render()
libsolidity/codegen/ABIFunctions.cpp
Outdated
} | ||
case Type::Category::Function: | ||
{ | ||
solAssert(false, "Cleanup should not be called for function types."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is conversion, not cleanup.
libsolidity/codegen/ABIFunctions.cpp
Outdated
} | ||
} | ||
|
||
string ABIFunctions::combineExternalFunctionIdFunction() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this next to cleanupCombinedExternalFunctionId
?
libsolidity/codegen/ABIFunctions.cpp
Outdated
_from.identifier() + | ||
"_to_" + | ||
_to.identifier() + | ||
(_encodeAsLibraryTypes ? "_lib" : ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably no point truncating it from _library
to _lib
.
<#word> | ||
mstore(add(pos, <offset>), <wordValue>) | ||
</word> | ||
end := add(pos, <overallSize>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could increment the pos
in-place in the loop and use end := add(pos, 64)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this way it is better for the optimizer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How so?
if (_to.isDynamicallySized()) | ||
{ | ||
Whiskers templ(R"( | ||
function <functionName>(pos) -> end { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, this one returns the occupied memory size but the other encoding functions below don't?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It returns the "new memory pointer" if and only if it is dynamically sized. You can take a look at how the functions are called, it is consistent and should be checked by the julia analyzer.
function <functionName>(src, dst, length) { | ||
calldatacopy(dst, src, length) | ||
// clear end | ||
mstore(add(dst, length), 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there an extra slot at the end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just removes potential garbage. The routine might write to more memory than it actually "returns" in the end. This is documented in the header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just feels weird this is not handled in the caller, why would it ask for more if the entire slot is cleared?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chriseth this question wasn't sorted out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ABI specification requires everything to be padded with zeros to multiples of 32 bytes. The calldatacopy only copies the actual length. This line performs the padding, especially in the case when the memory was pre-occupied by something else.
switch (_type.location()) | ||
{ | ||
case DataLocation::CallData: | ||
solAssert(false, "called regular array length function on calldata array"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because calldata arrays are stored as (pos, length)
, so you cannot retrieve the length from pos
alone.
libsolidity/codegen/ABIFunctions.cpp
Outdated
// because the encoding is position-independent, but we have to check that. | ||
Whiskers templ(R"( | ||
function <functionName>(start, length, pos) -> end { | ||
<storeLength> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add "// might update pos".
This is disabled for now (waiting for "experimental pragma").
Depends on: #2701 , #2700 , #2690
part of #2433